using System;
using System.Data.Linq.Mapping;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;

namespace MimeCloud.Foundations.Extensions
{
    public static class TypeExtensions
    {
        /// <summary>
        /// Gets the primary key.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public static PropertyInfo GetPrimaryKey(this Type entityType)
        {
            foreach (PropertyInfo property in entityType.GetProperties())
            {
                var attributes = (ColumnAttribute[]) property.GetCustomAttributes(
                                                         typeof (ColumnAttribute), true);
                if (attributes.Length == 1)
                {
                    ColumnAttribute columnAttribute = attributes[0];
                    if (columnAttribute.IsPrimaryKey)
                    {
                        if (property.PropertyType != typeof (int))
                        {
                            throw new ApplicationException(
                                string.Format("Primary key, '{0}', of type '{1}' is not int",
                                              property.Name, entityType));
                        }
                        return property;
                    }
                }
            }
            throw new ApplicationException(
                string.Format("No primary key defined for type {0}", entityType.Name));
        }

        /// <summary>
        /// Gets the attributes.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public static IEnumerable<T> GetAttributes<T>(this Type entityType)
        {
            var attributes = entityType.GetCustomAttributes(true);
            return attributes.OfType<T>();
        }

        /// <summary>
        /// Gets the attributes.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public static IEnumerable<T> GetAttributes<T>(this MethodInfo entityType)
        {
            var attributes = entityType.GetCustomAttributes(true);
            return attributes.OfType<T>();
        }

        /// <summary>
        /// Gets the attributes.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entityType">Type of the entity.</param>
        /// <returns></returns>
        public static IEnumerable<T> GetAttributes<T>(this PropertyInfo entityType)
        {
            var attributes = entityType.GetCustomAttributes(true);
            return attributes.OfType<T>();
        }
    }
}